package com.walle.ak47.commons.utils;

import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.WeakHashMap;

public class RuntimeUtils
{
	public final static String JAVA_VERSION = System.getProperty( "java.version" ) ;
	public final static String JAVA_VENDOR = System.getProperty( "java.vendor" ) ;
	public final static String JAVA_VENDOR_URL = System.getProperty( "java.vendor.url" ) ;
	public final static String JAVA_HOME = System.getProperty( "java.home" ) ;
	public final static String JAVA_CLASS_VERSION = System.getProperty( "java.class.version" ) ;
	public final static String JAVA_CLASS_PATH = System.getProperty( "java.class.path" ) ;
	public final static String JAVA_IO_TEMPDIR = System.getProperty( "java.io.tmpdir" ) ;
	public final static String OS_NAME = System.getProperty( "os.name" ) ;
	public final static String OS_ARCH = System.getProperty( "os.arch" ) ;
	public final static String OS_VERSION = System.getProperty( "os.version" ) ;
	public final static String FILE_SEPARATOR = System.getProperty( "file.separator" ) ;
	public final static String FILE_ENCODING = System.getProperty( "file.encoding" ) ;
	public final static String PATH_SEQARATOR = System.getProperty( "path.separator" ) ;
	public final static String LINE_SEPARATOR = System.getProperty( "line.separator" ) ;
	public final static String USER_NAME = System.getProperty( "user.name" ) ;
	public final static String USER_HOME = System.getProperty( "user.home" ) ;
	public final static String USER_DIR = System.getProperty( "user.dir" ) ;

	static ShutdownHook shutdownHook ;
	static String name ;
	
	static class ShutdownHook extends Thread
	{
		class CallbackObject
		{
			Object caller ;
			Method method ;
			Object[] params ;
			public Object getCaller()
			{
				return caller;
			}
			public void setCaller(Object caller)
			{
				this.caller = caller;
			}
			public Method getMethod()
			{
				return method;
			}
			public void setMethod(Method method)
			{
				this.method = method;
			}
			public Object[] getParams()
			{
				return params;
			}
			public void setParams(Object[] params)
			{
				this.params = params;
			}
		}
		
		WeakHashMap<Object,CallbackObject> shutdownHooks = new WeakHashMap<Object,CallbackObject>() ;
		
		public void run()
		{
			for( Map.Entry<Object, CallbackObject> entry : shutdownHooks.entrySet() )
			{
				CallbackObject callback = (CallbackObject)entry.getValue() ;
				try
				{
					if( callback.getCaller().getClass().equals( Class.class ) )
						callback.getMethod().invoke( ClassUtils.newInstance( callback.getMethod().getDeclaringClass() ) , callback.getParams() ) ;
					else
						callback.getMethod().invoke( callback.getCaller() , callback.getParams() ) ;
				}
				catch( Exception err )
				{}
			}
		}
		
		void setHook( Object _obj , Method _method , Object[] _params )
		{
			CallbackObject callback = new CallbackObject() ;
			callback.setCaller( _obj ) ;
			callback.setMethod( _method ) ;
			callback.setParams( _params ) ;
			
			shutdownHooks.put( _obj , callback ) ;
		}
	}
	
	public static synchronized void setShutdownHook( Object _instance , Method _method , Object[] _params )
	{
		if( shutdownHook == null )
		{
			shutdownHook = new ShutdownHook() ;
			Runtime.getRuntime().addShutdownHook( shutdownHook ) ;
		}
		
		shutdownHook.setHook( _instance , _method , _params ) ;
	}
	
	public static String getName()
	{
		if( name != null )
			return name ;
		name = ManagementFactory.getRuntimeMXBean().getName() ;
		return name ;
	}
	
	public static String getProjectResourcePath()
	{
		return Thread.currentThread().getContextClassLoader().getResource("").getPath();
	}
}
